import def from "./def";
import observe from "./observe";
const arrayProto = Array.prototype;

// 重写数组的七个方法的目的是，在改变数组结构的时候进行数据劫持
// push、unshift、splice 这三个方法会新增元素，需要对新增的元素进行响应式劫持（observe），确保新增元素也能被响应式追踪。
// pop、shift、splice 这三个方法会删除元素，通常删除元素不需要额外劫持，但如果你需要做删除的响应式通知（比如触发视图更新），可以在重写方法里做相应处理。
// sort、reverse 这两个方法只是改变数组顺序，不涉及新增或删除元素，一般只需要触发视图更新即可。

// 要重写的7个方法
const needChangeMethods = [
  "push",
  "pop",
  "shift",
  "unshift",
  "splice",
  "sort",
  "reverse",
];

// arrayMethods 重写的的原性对象
export const arrayMethods = Object.create(arrayProto);

needChangeMethods.forEach((methodName) => {
  const originMethod = arrayMethods[methodName];
  def(
    arrayMethods,
    methodName,
    function () {
      // 调用原始的方法
      const result = originMethod.apply(this, arguments);
      // 自己的重写方法
      console.log("重写的方法执行", methodName);

      // 对于 push shift splice 方法需要对新增的元素进行响应式处理
      let inserted;
      const arg = [...arguments];
      // 1：数组的元素增加
      switch (methodName) {
        case "push":
        case "unshift":
          inserted = arg;
          break;
        case "splice":
          inserted = arg.slice(2);
          break;
      }
      if (inserted) {
        // 对新增的元素进行响应式处理
        observe(inserted);
      }

      // 2: 数组的元素删除
      switch (methodName) {
        case "pop":
        case "shift":
          console.log("通知页面更新");
          break;
        case "splice":
          if (arg.length === 2) {
            console.log("通知页面更新");
          }
      }

      // 3: 数组的元素更新
      switch (methodName) {
        case "sort":
        case "reverse":
          console.log("通知页面更新");
          break;
      }
      return result;
    },
    false
  );
});
